package com.yuanxiao.client;

import com.yuanxiao.service.UserService;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

import org.apache.zookeeper.data.Stat;

import java.util.*;


public class ClientBootStrap {
   // public static final String providerName="UserService#sayHello#";
    private  static CuratorFramework client1;
    private static List<String> strings;
    public static void main(String[] args) throws Exception {


        //先去zk中获取所有的服务端地址
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        client1 = CuratorFrameworkFactory.builder()
                .connectString("192.168.0.105:2181") //server地址
                .sessionTimeoutMs(5000) // 会话超时时间
                .connectionTimeoutMs(3000) // 连接超时时间
                .retryPolicy(retryPolicy) // 重试策略
                .namespace("base") // ᇿ⽴命名空间/base
                .build(); //
        client1.start();
        String path ="/zkServer";
        System.out.println("Zookeeper session established. ");
        Stat stat = new Stat();

        /*
        UserService proxy = (UserService) rpcConsumer.createProxy(UserService.class,ip, port);
        */
        while (true){
            //Thread.sleep(2000);
            Thread.sleep(1000);
            try {

                    getZkList();

            } catch (Exception e) {
                e.printStackTrace();
            }
            /*try {
                client1.getChildren().usingWatcher(new Watcher() {
                    public void process(WatchedEvent watchedEvent) {
                        System.out.println(watchedEvent.getType());
                        if(watchedEvent.getType()== Event.EventType.NodeChildrenChanged){

                            System.out.println("列表发生变化了");
                            try {
                                getZkList();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).forPath(path);

            } catch (Exception e) {
                e.printStackTrace();
            }*/
            RpcConsumer rpcConsumer = new RpcConsumer();
            UserService proxy=null;
            /*
            设定/zkServer节点来存储响应对快的节点.后续取它来作为服务端发送.直到 最后更新时间大于5秒后.又全部节点重新发送一次,并统计最快节点来更新

             */

            byte[] byte_zkServer= client1.getData().storingStatIn(stat).forPath(path );
            if(byte_zkServer.length > 0){
                String s = new String(byte_zkServer);
                //System.out.println("======71"+stat.getMtime());
                long mtime = stat.getMtime();
                long startTime = System.currentTimeMillis();
                //System.out.println("======80"+startTime);
                if(startTime-mtime < 5000){
                    System.out.println("还没刷新,一当前的节点为准"+new String(byte_zkServer));
                    //超过了5秒 进行刷新重新全部服务器执行一次
                    String[] split1 = s.split(";");
                    for (String s1 : split1) {

                        String[] split = s1.split(":");
                        try {
                                proxy = (UserService) rpcConsumer.createProxy(UserService.class,split[0],Integer.valueOf(split[1]));
                                System.out.println("代理对象已经被创建...");
                                System.out.println(proxy.sayHello("are you ok?"));
                            }catch (Exception e){
                                continue;
                            }

                    }
                    continue;
                }
            }

            System.out.println("无节点数据,或已超过5秒");
            System.out.println(strings);
            SortedMap<String,Long> hashServerMap = new TreeMap<String,Long>();
            for (String string : strings) {
                byte[] bytes = client1.getData().forPath(path + "/" + string);
              String s = new String(bytes);

                String[] split = s.split(":");
                try {

                    proxy = (UserService) rpcConsumer.createProxy(UserService.class,split[0],Integer.valueOf(split[1]));
                    System.out.println("代理对象已经被创建...");
                    long startTime = System.currentTimeMillis();
                    System.out.println(proxy.sayHello("are you ok?"));
                    long endTime = System.currentTimeMillis();
                    long resopnseTime = endTime - startTime;
                    System.out.println(string+"----------响应时间为"+resopnseTime+"----------");
                    if(hashServerMap.isEmpty()){
                        hashServerMap.put(s+";",resopnseTime);
                    }else{
                        Long aLong = hashServerMap.get(hashServerMap.firstKey());
                        //如果当前响应时间小于map中存的时间,则清空map重新put
                        if(resopnseTime<aLong){
                            hashServerMap.clear();
                            hashServerMap.put(s+";",resopnseTime);
                        }else if(resopnseTime==aLong){
                            hashServerMap.put(s+";",resopnseTime);
                        }
                    }
                }catch (Exception e) {
                    continue;
                }
            }

            //处理map ,把最短时间的ip  xx,xx 的格式放入节点
            StringBuilder stringBuilder = new StringBuilder();
            Iterator<Map.Entry<String, Long>> iterator = hashServerMap.entrySet().iterator();
            while (iterator.hasNext()){
                System.out.println("当前map的大小是:" +hashServerMap.size());
                Map.Entry<String, Long> next = iterator.next();
                stringBuilder.append(next.getKey());
            }
            System.out.println("当前stringBuilder是:" +stringBuilder);
            client1.setData().forPath(path,stringBuilder.toString().getBytes());

        }

    }

    private static void getZkList() {
        //获取列表
        try {
            strings=client1.getChildren().forPath("/zkServer");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
